<template>
  <div>
    <div style="border-bottom: 1px solid #ebeef5; margin: 2px;">
      <el-button-group>
        <el-tooltip :open-delay="500" content="新建根目录" placement="top">
          <el-button icon="el-icon-folder-add" size="mini" type="primary" @click="addCatalog(null)" />
        </el-tooltip>
        <el-tooltip :content="`新建${eTitle}`" :open-delay="500" placement="top">
          <el-button icon="el-icon-document-add" size="mini" type="primary" @click="addElement(0)" />
        </el-tooltip>
        <el-tooltip :open-delay="500" content="搜索" placement="top">
          <el-button size="mini" type="primary" @click="handleClickSearch"><svg-icon icon-class="search" /></el-button>
        </el-tooltip>
      </el-button-group>
    </div>
    <splitpanes style="height: 87vh">
      <pane :min-size="10" :size="30">
        <div style="width: 100%; height: 100%;">
          <div id="leftDiv" style="overflow-y: scroll; height: 100%;">
            <tree-component
              ref="treeComponent"
              :element-label="eTitle"
              catalog-label="目录"
              draggable
              lazy
              @tree-content="treeContent"
              @tree-sort="treeSort"
              @choose-catalog="chooseCatalog"
              @reload-catalog="reloadCatalog"
              @copy-catalog="copyCatalog"
              @add-catalog="addCatalog"
              @delete-catalog="deleteCatalog"
              @choose-element="chooseElement"
              @add-element="addElement"
              @delete-element="deleteElement"
              @copy-element="copyElement"
            />
          </div>
        </div>
      </pane>
      <pane :min-size="20" :size="70">
        <div id="rightDiv" style="overflow-y: scroll; width: 100%; height: 98%;">
          <el-tabs v-if="activeName" v-model="activeName" style="width: 100%;" type="border-card">
            <el-tab-pane v-if="activeName === 'catalog'" label="目录" name="catalog">
              <catalog-component
                ref="catalogComponent"
                :catalog-info="catalog"
                :type="eType"
                @create="createCatalog"
                @update="updateCatalog"
              />
            </el-tab-pane>
            <el-tab-pane v-if="activeName === 'element'" :label="eTitle" name="element">
              <div style="text-align: right">
                <el-button-group style="margin-top: 0px; margin-right: 12px; margin-bottom: 4px;">
                  <el-tooltip :open-delay="500" content="历史记录" placement="top">
                    <el-button :disabled="element.id===undefined" icon="el-icon-link" size="mini" type="info" @click="handleHistory" />
                  </el-tooltip>
                  <el-tooltip :open-delay="500" content="保存" placement="top">
                    <el-button icon-class="skill" size="mini" type="primary" @click="saveElement"><svg-icon icon-class="save" /></el-button>
                  </el-tooltip>
                </el-button-group>
              </div>
              <el-card shadow="hover">
                <el-alert close-text="Get!" show-icon style="margin-bottom: 10px" title="SSH 服务器信息，当执行 shell 命令时直接选择对应名称的服务器即可。" type="info">
                  <div>1、名称：起一个合理的名字更容易记住</div>
                  <div>2、HOST / IP：需要登录 SSH 服务器的 HOST 或 IP</div>
                  <div>3、PORT：SSH 服务的端口号</div>
                  <div>4、用户名 + 密码认证：使用 用户名+密码 方式验证登录</div>
                  <div>5、JumpServer 跳板机：需要登录的 SSH 服务器是不是 JumpServer 跳板机</div>
                  <div>6、资产 ID 或 IP：如果是 JumpServer 跳板机需要输入此字段，会在成功连接跳板机后自动连接此服务器</div>
                </el-alert>
                <el-form ref="element" :model="element" :rules="rules" class="demo-table-expand" label-position="left" label-width="100px" size="small">
                  <el-form-item label="名称" prop="name">
                    <el-input v-model="element.name" placeholder="请输入名称" />
                  </el-form-item>
                  <el-form-item label="HOST / IP" prop="uri">
                    <el-input v-model="element.uri" placeholder="请输入 HOST / IP" />
                  </el-form-item>
                  <el-form-item label="PORT" prop="apiParams[0].example">
                    <el-input v-model="element.apiParams[0].example" maxlength="5" placeholder="请输入 PORT" />
                  </el-form-item>
                  <el-form-item>
                    <el-checkbox v-model="element.apiParams[1].example" label="用户名 + 密码认证" name="passwordAuth" @change="passwordAuthChange" />
                  </el-form-item>
                  <el-form-item v-show="element.apiParams[1].example" label="用户名">
                    <el-input v-model="element.apiParams[4].example" placeholder="请输入登录 SSH 服务器的用户名" />
                  </el-form-item>
                  <el-form-item v-show="element.apiParams[1].example" label="密码">
                    <el-input v-model="element.apiParams[5].example" placeholder="请输入登录 SSH 服务器的密码" />
                  </el-form-item>
                  <el-form-item>
                    <el-checkbox v-model="element.apiParams[2].example" label="JumpServer 跳板机" name="passwordAuth" />
                  </el-form-item>
                  <el-form-item label="资产 ID 或 IP" prop="apiParams[3].example">
                    <el-input v-model="element.apiParams[3].example" />
                  </el-form-item>
                </el-form>
              </el-card>
            </el-tab-pane>
          </el-tabs>
        </div>
      </pane>
    </splitpanes>

    <el-dialog :visible.sync="searchDialogFormVisible" title="搜索" width="1200px" :close-on-click-modal="false">
      <interface-search-component
        ref="interfaceSearchComponent"
        :type="eType"
        @dblclickResultRow="dblclickResultRow"
      />
    </el-dialog>

    <el-dialog :visible.sync="historyDialogFormVisible" title="历史记录" width="1200px" :close-on-click-modal="false">
      <api-history-component
        ref="apiHistoryComponent"
        @dblclickResultRow="dblclickHistoryRow"
      />
    </el-dialog>
  </div>
</template>

<style>
.splitpanes__pane {
  justify-content: flex-start;
  align-items: flex-start;
  display: flex;
  border: 1px solid #ebeef5;
}
.splitpanes__splitter {
  width: 5px;
  margin-left: -1px
}
#leftDiv::-webkit-scrollbar, #rightDiv::-webkit-scrollbar {
  width: 0px;
}
</style>

<script>
import { Pane, Splitpanes } from 'splitpanes'
import 'splitpanes/dist/splitpanes.css'
import TreeComponent from '@/components/functional_test/Tree/index.vue'
import CatalogComponent from '@/components/functional_test/Catalog/index.vue'
import InterfaceSearchComponent from '@/components/functional_test/Search/interfaceSearch.vue'
import { validPositiveInteger } from '@/utils/validate'
import { copy as catalogCopy, del as catalogDel, listTreeContent, treeSort } from '@/api/functional_test/catalog'
import {
  create as apiCreate,
  del as apiDel,
  selectById as apiSelectById,
  update as apiUpdate
} from '@/api/functional_test/test_data_manage/api'
import ApiHistoryComponent from '@/components/functional_test/History/apiHistory'

export default {
  components: { Splitpanes, Pane, TreeComponent, CatalogComponent, InterfaceSearchComponent, ApiHistoryComponent },
  filters: {
    statusFilter(status) {
      const statusMap = {
        published: 'success',
        draft: 'gray',
        deleted: 'danger'
      }
      return statusMap[status]
    }
  },
  data() {
    const validateServerIp = (rule, value, callback) => {
      if (this.element.apiParams[2].example && value.trim().length === 0) {
        callback(new Error('如果是 JumpServer 跳板机需要输入资产 ID 或 IP'))
      } else {
        callback()
      }
    }
    return {
      searchDialogFormVisible: false,
      eType: 15, // 元素类型
      eTitle: ' SSH 服务器',
      activeName: null, // 当前激活的 tab 名称
      currentCatalogId: 0, // 当前选中的 catalog ID
      catalog: {}, // catalog 对象
      element: {}, // element 对象
      historyDialogFormVisible: false, // 历史记录弹窗
      rules: {
        name: [
          { required: true, message: '名称不能为空', trigger: 'blur' },
          { max: 100, message: '名称长度不能超过 100 个字符', trigger: 'blur' }
        ],
        uri: [
          { required: true, message: '请输入 HOST', trigger: 'blur' },
          { max: 255, message: 'HOST 长度不能超过 255 个字符', trigger: 'blur' }
        ],
        'apiParams[0].example': [
          { required: true, message: '请输入 PORT', trigger: 'blur' },
          { validator: validPositiveInteger, message: 'PORT 只能输入正整数', trigger: 'blur' }
        ],
        'apiParams[3].example': [
          { trigger: 'blur', validator: validateServerIp },
          { max: 100, message: '资产 ID 或 IP 长度不能超过 100 个字符', trigger: 'blur' }
        ]
      }
    }
  },
  created() {
  },
  methods: {
    // 新增时初始化 element 数据
    resetElement() {
      this.element = {
        'projectId': this.$store.getters.projectId,
        'catalogId': this.currentCatalogId,
        'type': this.eType,
        'name': '',
        'url': '',
        'apiParams': [
          {
            'name': 'port',
            'des': '端口号',
            'example': '22',
            'required': false,
            'kind': 0,
            'sort': 1
          },
          {
            'name': 'isPasswordAuth',
            'des': '是否用户名+密码登录',
            'example': true,
            'required': false,
            'kind': 0,
            'sort': 2
          },
          {
            'name': 'isJumpServer',
            'des': '是否 JumpServer 跳板机',
            'example': true,
            'required': false,
            'kind': 0,
            'sort': 3
          },
          {
            'name': 'serverIp',
            'des': '资产 ID 或 IP',
            'example': '',
            'required': false,
            'kind': 0,
            'sort': 4
          },
          {
            'name': 'userName',
            'des': '用户名',
            'example': '',
            'required': false,
            'kind': 0,
            'sort': 5
          },
          {
            'name': 'password',
            'des': '密码',
            'example': '',
            'required': false,
            'kind': 0,
            'sort': 6
          }
        ]
      }
    },
    // 设置 element 数据（当服务端返回数据后有些类型不符需要在这个方法中转换）
    setElement(ele) {
      this.element = ele

      this.element.apiParams[1].example = JSON.parse(this.element.apiParams[1].example) // isPasswordAuth 的值转成 boolean
      this.element.apiParams[2].example = JSON.parse(this.element.apiParams[2].example) // isJumpServer 的值转成 boolean
    },
    // tree：装载当前树节点数据
    treeContent(parentId, resolve) {
      listTreeContent({
        projectId: this.$store.getters.projectId,
        type: this.eType,
        parentId: parentId
      }).then(response => {
        resolve(response.data)
      })
    },
    // tree：拖拽排序
    treeSort(draggingNode, dropNode, dropType) {
      treeSort(this.$store.getters.projectId, this.eType, draggingNode.data, dropNode.data, dropType).then(response => {
        this.$message({ message: '修改排序成功!', type: 'success' })
      })
    },
    // tree：点击一个分类后调用此方法
    chooseCatalog(id) {
      this.activeName = 'catalog' // 设置当前 tab catalog
      this.currentCatalogId = this.catalog.id
      this.$nextTick(() => {
        this.$refs.catalogComponent.loadData(id)
      })
    },
    // tree：点击刷新一个分类的按钮后回调此方法
    reloadCatalog() {
      this.activeName = null // 清除 tab activeName
    },
    // tree：点击复制一个分类后调此方法
    copyCatalog(id, resolve) {
      catalogCopy(this.eType, this.$store.getters.projectId, id).then(response => {
        resolve(response.data)
      })
    },
    // tree：点击添加一个分类后调此方法
    addCatalog(parent_id) {
      this.activeName = 'catalog' // 设置当前 tab catalog
      this.$nextTick(() => {
        this.$refs.catalogComponent.add(parent_id)
      })
    },
    // tree：点击复制一个元素后调此方法
    copyElement(parent_id, id) {
      this.currentCatalogId = parent_id
      this.activeName = 'element' // 设置当前 tab element
      this.$nextTick(() => {
        apiSelectById(this.eType, id).then(response => {
          response.data.id = undefined
          if (response.data.apiParams) {
            response.data.apiParams.forEach(function(item) {
              item.id = undefined
            })
          }
          this.$nextTick(() => {
            this.setElement(response.data)
          })
        })
      })
    },
    // tree：http接口定义修改成功后回调此方法
    updateElement(elementInfo) {
      this.$refs.treeComponent.updateNode(elementInfo)
    },
    // tree：分类添加成功后回调此方法
    createCatalog(catalogInfo) {
      this.catalog = catalogInfo
      this.$refs.treeComponent.appendNode(catalogInfo.id, catalogInfo.parentId, catalogInfo.name, true, null, null)
    },
    // tree：分类修改成功后回调此方法
    updateCatalog(catalogInfo) {
      this.catalog = catalogInfo
      this.$refs.treeComponent.updateNode(catalogInfo)
    },
    // tree：删除一个分类
    deleteCatalog(id, resolve) {
      catalogDel(this.$store.getters.projectId, this.eType, id).then(response => {
        resolve()
        this.activeName = null // 清除 tab activeName
      })
    },
    // tree：点击一个元素后调用此方法
    chooseElement(id) {
      apiSelectById(this.eType, id).then(response => {
        this.activeName = 'element' // 设置当前 tab element
        this.setElement(response.data)
      })
    },
    // tree：点击添加一个元素后调此方法
    addElement(parent_id) {
      this.currentCatalogId = parent_id
      this.resetElement()
      this.activeName = 'element' // 设置当前 tab element
    },
    // 点击元素保存按钮调用此方法
    saveElement: function() {
      this.$refs['element'].validate((valid) => {
        if (valid) {
          if (!this.element.id) { // 新增 element
            apiCreate(this.element).then(response => {
              this.setElement(response.data)
              this.$refs.treeComponent.appendNode(this.element.id, this.element.catalogId, this.element.name, 'false', null, null)
              this.$message({ message: '添加成功!', type: 'success' })
            })
          } else { // 修改 element
            apiUpdate(this.element).then(response => {
              this.setElement(response.data)
              this.$refs.treeComponent.updateNode(this.element)
              this.$message({ message: '保存成功!', type: 'success' })
            })
          }
        }
      })
    },
    // tree：删除一个元素
    deleteElement(id, resolve) {
      apiDel(this.eType, id).then(response => { // 这里要改成 delElement
        resolve()
        this.activeName = null // 清除 tab activeName
      })
    },
    passwordAuthChange(val) {
      if (!val) {
        this.element.apiParams[4].example = '' // 用户名
        this.element.apiParams[5].example = '' // 密码
      }
    },
    // 单击搜索按钮
    handleClickSearch() {
      this.searchDialogFormVisible = true
    },
    // 双击搜索结果行
    dblclickResultRow(elementParent) {
      this.searchDialogFormVisible = false
      this.$refs.treeComponent.setCurrentNode(elementParent)
    },
    // 点击 history 按钮
    handleHistory() {
      this.historyDialogFormVisible = true
      this.$nextTick(() => {
        this.$refs.apiHistoryComponent.loadData(this.element.id)
      })
    },
    // 双击历史结果行
    dblclickHistoryRow(ele) {
      this.historyDialogFormVisible = false
      this.setElement(ele)
    }
  }
}
</script>
